"""
Metric decomposition node - decomposes complex metrics into components.
"""
from typing import Dict, Any
from ..tools.metrics import MetricCalculator
from ..tools.data_loader import DataLoader
from ..models.schemas import MetricConfig, DecompositionType


def decompose_metric(state: Dict[str, Any]) -> Dict[str, Any]:
    """
    Decompose the target metric into components.

    Args:
        state: Current state dict

    Returns:
        Updated state dict with decomposition results
    """
    data = state.get('data')
    target_metric = state.get('target_metric', 'revenue')
    metric_metadata = state.get('metric_metadata', {})

    if data is None or data.empty:
        state['decomposition'] = None
        state['next_action'] = 'reasoning'
        return state

    # Initialize tools
    loader = DataLoader()
    calculator = MetricCalculator()

    # Split data into current and baseline periods
    time_range = state.get('time_range')
    baseline_period = state.get('baseline_period')

    current_df, baseline_df = loader.split_by_period(
        data,
        'date',
        time_range,
        baseline_period
    )

    try:
        # Check if metric can be decomposed
        # This is a simplified example - in production, you would have
        # predefined metric configurations
        metric_config = _get_metric_config(target_metric, data.columns.tolist())

        if metric_config and metric_config.components:
            # Perform decomposition
            decomposition = calculator.decompose_metric(
                current_df,
                baseline_df,
                metric_config
            )

            state['decomposition'] = decomposition.dict()

            # Analyze contributions
            contributions = {}
            for component, contrib in decomposition.component_contributions.items():
                contributions[component] = contrib

            state['contribution_analysis'] = contributions
        else:
            # No decomposition available for this metric
            state['decomposition'] = None
            state['contribution_analysis'] = {}

    except Exception as e:
        state['error'] = f"Metric decomposition failed: {str(e)}"
        state['decomposition'] = None

    state['next_action'] = 'reasoning'
    return state


def _get_metric_config(metric_name: str, available_columns: list) -> MetricConfig:
    """
    Get metric configuration based on metric name and available columns.

    This is a simplified example. In production, you would have a
    metric registry or configuration file.
    """
    # Common metric decompositions
    metric_configs = {
        'revenue': MetricConfig(
            name='revenue',
            display_name='Revenue',
            formula='price * quantity',
            decomposition_type=DecompositionType.MULTIPLICATIVE,
            components=['price', 'quantity'] if 'price' in available_columns and 'quantity' in available_columns else None
        ),
        'conversion_rate': MetricConfig(
            name='conversion_rate',
            display_name='Conversion Rate',
            formula='conversions / visits',
            decomposition_type=DecompositionType.RATIO,
            components=['conversions', 'visits'] if 'conversions' in available_columns and 'visits' in available_columns else None
        ),
        'profit': MetricConfig(
            name='profit',
            display_name='Profit',
            formula='revenue - cost',
            decomposition_type=DecompositionType.ADDITIVE,
            components=['revenue', 'cost'] if 'revenue' in available_columns and 'cost' in available_columns else None
        ),
        'arpu': MetricConfig(
            name='arpu',
            display_name='ARPU',
            formula='revenue / users',
            decomposition_type=DecompositionType.RATIO,
            components=['revenue', 'users'] if 'revenue' in available_columns and 'users' in available_columns else None
        ),
        'ctr': MetricConfig(
            name='ctr',
            display_name='CTR',
            formula='clicks / impressions',
            decomposition_type=DecompositionType.RATIO,
            components=['clicks', 'impressions'] if 'clicks' in available_columns and 'impressions' in available_columns else None
        ),
    }

    return metric_configs.get(metric_name.lower())
